'use strict';
const { resolve } = require('path');
const npmInstall = require('npminstall');
const pkgDir = require('pkg-dir');
const pathExists = require('path-exists');
const fse = require('fs-extra');
const { isObject } = require('@ysx-cli/utils');
const formatPath = require('@ysx-cli/format-path');
const { defaultRegistry, npmLatestVersion } = require('@ysx-cli/npm-info');

class Package {
  constructor(options) {
    if (isObject(options)) {
      // 目标路径
      this.targetPath = options.targetPath;

      // npm i 时缓存的路径
      this.storeDir = options.storeDir;
      // this.storePath = options.storePath;
      this.packageName = options.packageName; // eg: @ysx-cli/create
      this.packageVersion = options.packageVersion;

      this.cacheFilePath = this.setCacheFilePath(this.packageVersion);
    }
  }

  setCacheFilePath(packageVersion) {
    // console.log('setCacheFilePath targetPath', this.targetPath);
    // 缓存目录的前缀
    const cacheFilePathPrefix = this.packageName.replace('/', '_');
    // @ysx-cli/create 1.0.1 => _@ysx-cli_create@1.0.1@@ysx-cli/create
    return this.storeDir ? resolve(this.storeDir, `_${cacheFilePathPrefix}@${packageVersion}@${this.packageName}`) : '';
  }




  async prepare() {
    if (this.storeDir && !pathExists(this.storeDir)) {
      // this.storeDir 这条路径上不存在的目录全创建出来
      fse.mkdirpSync(this.storeDir);
    }
    // get latest 对应的版本号
    if (this.packageVersion === 'latest') {
      this.packageVersion = await npmLatestVersion(this.packageName);
      this.cacheFilePath = this.setCacheFilePath(this.packageVersion);
    }
  }
  async exists() {
    if (this.storeDir) {
      await this.prepare();
      return pathExists(this.cacheFilePath);
    }
    return pathExists(this.targetPath);
  }
  async install() {
    await this.prepare();
    return npmInstall({
      root: this.targetPath,
      storePath: this.storeDir,
      registry: defaultRegistry,
      pkgs: [
        { name: this.packageName, version: this.packageVersion }
      ]
    });
  }
  async update() {
    await this.prepare();
    const latestVersion = await npmLatestVersion(this.packageName);
    this.cacheFilePath = this.setCacheFilePath(latestVersion);
    if (!pathExists.sync(this.cacheFilePath)) {
      await npmInstall({
        root: this.targetPath,
        storePath: this.storeDir,
        registry: defaultRegistry,
        pkgs: [
          { name: this.packageName, version: latestVersion }
        ]
      });
    }
    this.packageVersion = latestVersion;
  }

  // 获取入口文件路径
  entryFilePath() {
    let result = '';
    const _getEntryFile = targetPath => {
      const entryDir = pkgDir.sync(targetPath);
      if (entryDir) {
        const pkgFile = require(resolve(entryDir, 'package.json'));
        if (pkgFile && pkgFile.main) {
          result = formatPath(resolve(entryDir, pkgFile.main));
        }
      }
    }
    if (this.storeDir) { // 使用缓存
      _getEntryFile(this.cacheFilePath);
    } else {
      _getEntryFile(this.targetPath);
    }

    return result;
  }
}
module.exports = Package;
